package com.yuanchu.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.yuanchu.common.exception.YuanChuException;
import com.yuanchu.common.utils.DateFormatUtils;
import com.yuanchu.common.utils.PageResult;
import com.yuanchu.search.client.FeignGoodsClient;
import com.yuanchu.search.client.FeignOrderClient;
import com.yuanchu.search.dto.OrderDetailDto;
import com.yuanchu.search.dto.QueryOrderParamsDto;
import com.yuanchu.search.dto.TradeTrendVO;
import com.yuanchu.search.dto.UserOrderCountsDto;
import com.yuanchu.search.entity.YoshopOrderEntity;
import com.yuanchu.search.entity.YoshopOrderRefundEntity;
import com.yuanchu.search.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.search.TotalHits;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.BucketOrder;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.ParsedStats;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @version: 1.0
 * @Author: adan
 * @description:
 * @date: 2024-02-29 13:06
 */
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
    @Resource
    private RestHighLevelClient client;
    @Resource
    private FeignOrderClient feignOrderClient;
    @Resource
    private FeignGoodsClient feignGoodsClient;
    @Override
    public PageResult<OrderDetailDto> queryStoreOrderList(QueryOrderParamsDto param) {
        Integer searchType = param.getSearchType(); // 搜索类型
        Integer page = param.getPage(); // 页码
        String searchValue = param.getSearchValue();    // 搜索值
        Integer deliveryType = param.getDeliveryType(); // 物流方式
        Integer payType = param.getPayType();   // 支付方式
        long betweenTimeStart = convertStringToSeconds(param.getBetweenTimeStart());  // 时间区间
        long betweenTimeEnd = convertStringToSeconds(param.getBetweenTimeEnd());
        // 设置索引
        SearchRequest searchRequest = new SearchRequest("yuanchu_order");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // 构建条件查询
        BoolQueryBuilder boolQueryBuilder = buildBasicQuery(param, searchType, searchValue, deliveryType, payType, betweenTimeStart, betweenTimeEnd);

        // 分页
        Integer pageNo = param.getPage();
        Integer pageSize = param.getPageSize();
        int start = (pageNo - 1) * pageSize;
        searchSourceBuilder.from(start);
        searchSourceBuilder.size(Math.toIntExact(pageSize));
        // 布尔查询
        searchSourceBuilder.query(boolQueryBuilder)
                .sort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC));
        // 请求搜索
        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = null;
        try {
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("搜索异常：{}", e.getMessage());
            return PageResult.formatPageResult(Collections.emptyList(), pageNo, pageSize);
        }

        // 结果集处理
        SearchHits hits = searchResponse.getHits();
        SearchHit[] searchHits = hits.getHits();
        // 记录总数
        TotalHits totalHits = hits.getTotalHits();
        // 数据列表
        List<OrderDetailDto> list = new ArrayList<>();

        for (SearchHit hit : searchHits) {
            String sourceAsString = hit.getSourceAsString();
            OrderDetailDto orderDetail = JSON.parseObject(sourceAsString, OrderDetailDto.class);
            orderDetail.setCreateTime(DateFormatUtils.formatDatetime(orderDetail.getCreateTime()));
            orderDetail.setAddress(null);
            list.add(orderDetail);
        }
        return PageResult.formatPageResult(list, pageNo, pageSize, totalHits.value);
    }


    private static BoolQueryBuilder buildBasicQuery(QueryOrderParamsDto param, Integer searchType, String searchValue,
                                                    Integer deliveryType, Integer payType, long betweenTimeStart, long betweenTimeEnd) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        // 关键字
        if (StringUtils.isNotEmpty(searchValue)) {
            // 搜索类型
            if (searchType == 10) {
                // 订单号
                boolQueryBuilder.must(QueryBuilders.matchQuery("orderNo", searchValue));
            } else if (searchType == 20) {
                // 会员昵称，匹配关键字
                boolQueryBuilder.must(QueryBuilders.matchQuery("user.nickName", searchValue));
            } else if (searchType == 30) {
                // 会员id
                boolQueryBuilder.must(QueryBuilders.termQuery("userId", searchValue));
            } else if (searchType == 40) {
                // 收货人姓名
                boolQueryBuilder.must(QueryBuilders.matchQuery("address.name", searchValue));
            } else if (searchType == 50) {
                // 收货人电话
                boolQueryBuilder.must(QueryBuilders.termQuery("address.phone", searchValue));
            }
        }
        // 过虑
        // 时间区间
        if (betweenTimeStart > 0 && betweenTimeEnd > 0) {
            RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("createTime");
            rangeQuery.lte(betweenTimeEnd);
            rangeQuery.gte(betweenTimeStart);
            boolQueryBuilder.filter(rangeQuery);
        }
        Integer orderSource = param.getOrderSource();   // 订单来源
        if (orderSource != null && orderSource > 0) {
            boolQueryBuilder.must(QueryBuilders.termQuery("orderSource", orderSource));
        }
        String dataType = param.getDataType();  // 订单类型
        // 判断订单类型
        if ("pay".equals(dataType)) {
            //  订单状态(10进行中、待支付
            boolQueryBuilder.must(QueryBuilders.termQuery("orderStatus", 10));
            boolQueryBuilder.must(QueryBuilders.termQuery("payStatus", 10));
        } else if ("delivery".equals(dataType)) {
            // 待发货 、已支付
            boolQueryBuilder.must(QueryBuilders.termQuery("payStatus", 20))
                    .must(QueryBuilders.termQuery("deliveryStatus", 10))
                    .mustNot(QueryBuilders.termQuery("orderStatus", 20));
        } else if ("receipt".equals(dataType)) {
            // 待收货、已发货
            boolQueryBuilder.must(QueryBuilders.termQuery("deliveryStatus", 20));
            boolQueryBuilder.must(QueryBuilders.termQuery("receiptStatus", 10));
        } else if ("complete".equals(dataType)) {
            // 已完成
            boolQueryBuilder.must(QueryBuilders.termQuery("orderStatus", 30));
        } else if ("cancel".equals(dataType)) {
            // 已取消
            boolQueryBuilder.must(QueryBuilders.termQuery("orderStatus", 20));
        }
        // 支付方式
        if (payType != null && payType > -1) {
            boolQueryBuilder.must(QueryBuilders.termQuery("payType", payType));
        }
        // 配送方式
        if (deliveryType != null && deliveryType != -1) {
            boolQueryBuilder.must(QueryBuilders.termQuery("deliveryType", deliveryType));
        }
        return boolQueryBuilder;
    }

    @Override
    public OrderDetailDto getStoreOrderDetail(Integer orderId, Integer storeId) {
        // 1、从es查询
        // 设置索引
        // 1.准备Request
        GetRequest request = new GetRequest("yuanchu_order", String.valueOf(orderId));
        // 2.发送请求，得到响应
        GetResponse response = null;
        try {
            response = client.get(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 3.解析响应结果
        String json = response.getSourceAsString();
        OrderDetailDto orderSearch = JSON.parseObject(json, OrderDetailDto.class);
        if (orderSearch != null) {
            orderSearch.setCreateTime(DateFormatUtils.formatDatetime(orderSearch.getCreateTime()));
            return orderSearch;
        }
        // 2、调用接口查询
        return feignOrderClient.queryStoreOrderDetail(orderId);
    }

    @Override
    public OrderDetailDto getOrderDetailByOrderId(Integer orderId, Integer userId) {
        // 1、从es查询
        // 设置索引
        // 1.准备Request
        GetRequest request = new GetRequest("yuanchu_order", String.valueOf(orderId));
        // 2.发送请求，得到响应
        GetResponse response = null;
        try {
            response = client.get(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 3.解析响应结果
        String json = response.getSourceAsString();
        OrderDetailDto orderSearch = JSON.parseObject(json, OrderDetailDto.class);
        if (orderSearch != null) {
            orderSearch.setCreateTime(DateFormatUtils.formatDatetime(orderSearch.getCreateTime()));
            return orderSearch;
        }
        // 2、调用接口查询
        return feignOrderClient.getOrderDetail(orderId);
    }

    @Override
    public PageResult<OrderDetailDto> queryOrderList(String dataType, Integer page, Integer userId) {
        // 设置索引
        SearchRequest searchRequest = new SearchRequest("yuanchu_order");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("userId", userId));
        // 判断订单类型
        buildOrderTypeSearch(dataType, boolQueryBuilder);
        // 分页
        Integer pageNo = page;
        Integer pageSize = 10;
        int start = (pageNo - 1) * pageSize;
        searchSourceBuilder.from(start);
        searchSourceBuilder.size(Math.toIntExact(pageSize));
        // 布尔查询
        searchSourceBuilder.query(boolQueryBuilder).sort(SortBuilders.fieldSort("createTime").order(SortOrder.DESC));
        // 请求搜索
        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = null;
        try {
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("课程搜索异常：{}", e.getMessage());
            return PageResult.formatPageResult(Collections.emptyList(), pageNo, pageSize);
        }

        // 结果集处理
        SearchHits hits = searchResponse.getHits();
        SearchHit[] searchHits = hits.getHits();
        // 记录总数
        TotalHits totalHits = hits.getTotalHits();
        // 数据列表
        List<OrderDetailDto> list = new ArrayList<>();

        for (SearchHit hit : searchHits) {
            String sourceAsString = hit.getSourceAsString();
            OrderDetailDto orderDetail = JSON.parseObject(sourceAsString, OrderDetailDto.class);
            orderDetail.setCreateTime(DateFormatUtils.formatDatetime(orderDetail.getCreateTime()));
            list.add(orderDetail);
        }
        return PageResult.formatPageResult(list, pageNo, pageSize, totalHits.value);
    }

    private static void buildOrderTypeSearch(String dataType, BoolQueryBuilder boolQueryBuilder) {
        if ("payment".equals(dataType)) {
            //  订单状态(10进行中、待支付
            boolQueryBuilder.must(QueryBuilders.termQuery("orderStatus", 10));
            boolQueryBuilder.must(QueryBuilders.termQuery("payStatus", 10));
        } else if ("delivery".equals(dataType)) {
            // 待发货 、已支付
            boolQueryBuilder.must(QueryBuilders.termQuery("orderStatus", 10));
            boolQueryBuilder.must(QueryBuilders.termQuery("payStatus", 20));
            boolQueryBuilder.must(QueryBuilders.termQuery("deliveryStatus", 10));
        } else if ("received".equals(dataType)) {
            // 已发货  待收货
            boolQueryBuilder.must(QueryBuilders.termQuery("orderStatus", 10));
            boolQueryBuilder.must(QueryBuilders.termQuery("deliveryStatus", 20));
            boolQueryBuilder.must(QueryBuilders.termQuery("receiptStatus", 10));
        } else if ("comment".equals(dataType)) {
            // 已完成
            boolQueryBuilder.must(QueryBuilders.termQuery("orderStatus", 30));
        }
    }

    @Override
    public UserOrderCountsDto queryOrderCounts(Integer userId) {
        // 1.准备Request
        SearchRequest request = new SearchRequest("yuanchu_order");
        // 2.准备DSL
        // 2.1.准备BooleanQuery
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 2.2.添加term
        boolQuery.must(QueryBuilders.termQuery("userId", userId));
        request.source().query(boolQuery).size(1000);
        // 3.发送请求
        SearchResponse response = null;
        try {
            response = client.search(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException("查询es数据异常");
        }
        // 4.解析响应
        List<OrderDetailDto> orderList = handleResponse(response, OrderDetailDto.class);
        // 统计待发货订单 delivery_status 发货状态(10未发货 20已发货) && 付款状态(10未付款 20已付款)
        List<YoshopOrderEntity> payOrders = orderList.stream().
                filter(order -> order.getOrderStatus() == 10).
                filter(order -> order.getPayStatus() == 20).collect(Collectors.toList());
        long deliveryOrders = payOrders.stream().filter(order -> order.getDeliveryStatus() == 10).count();
        // 统计待收货订单 receipt_status 收货状态(10未收货 20已收货)
        long receiptOrders = payOrders.stream()
                .filter(order -> order.getOrderStatus() == 10)
                .filter(order -> order.getDeliveryStatus() == 20)
                .filter(order -> order.getReceiptStatus() == 10).count();
        // 统计待付款订单 pay_status 支付状态(10未付款 20已付款)
        long disPayOrders = orderList.stream().
                filter(order -> order.getOrderStatus() == 10)
                .filter(order -> order.getPayStatus() == 10).count();
        // 统计售后订单 refund_status 退款状态(10未退款 20已退款)
        List<YoshopOrderRefundEntity> orderRefunds = queryOrderRefunds(userId);
        long orderRefundTotal = orderRefunds.stream().filter(order -> order.getStatus() == 0).count();

        UserOrderCountsDto userOrderCounts = new UserOrderCountsDto();
        userOrderCounts.setDelivery((int) deliveryOrders);
        userOrderCounts.setReceived((int) receiptOrders);
        userOrderCounts.setPayment((int) disPayOrders);
        userOrderCounts.setRefund((int) orderRefundTotal);
        return userOrderCounts;
    }

    @Override
    public TradeTrendVO getTradeTrend() {
        Instant sevenDaysAgoInstant = Instant.now().minus(Duration.ofDays(7));
        long sevenDaysAgoEpochSecond = sevenDaysAgoInstant.getEpochSecond();

        // 创建搜索请求
        SearchRequest searchRequest = new SearchRequest("yuanchu_order");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 添加时间范围过滤器
        searchSourceBuilder.query(QueryBuilders.rangeQuery("createTime")
                .gte(sevenDaysAgoEpochSecond)
                .lte(Instant.now().getEpochSecond() / 1000));
        searchSourceBuilder.size(1000);
        // 按时间降序排序
        // searchSourceBuilder.sort("createTime", SortOrder.ASC);
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = null;
        // 执行搜索请求
        try {
            response = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new YuanChuException("查询es数据异常");
        }
        List<OrderDetailDto> orderList = handleResponse(response, OrderDetailDto.class);
        orderList.stream().sorted(Comparator.comparing(OrderDetailDto::getCreateTime));
        // 初始化TradeTrendVO对象
        TradeTrendVO trend = new TradeTrendVO();
        List<String> dateList = new ArrayList<>();
        List<String> orderTotalList = new ArrayList<>();
        List<String> orderTotalPriceList = new ArrayList<>();
        // 初始化日期和数据列表
        for (int i = 6; i >= 0; i--) {
            String date = LocalDate.now().minusDays(i).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            dateList.add(date);
            orderTotalList.add("0");
            orderTotalPriceList.add(String.valueOf(BigDecimal.ZERO));
        }
        orderList.forEach(order -> {
            // 日期
            String date = DateFormatUtils.formatDatetimeFormat02(order.getCreateTime());
            order.setCreateTime(date);
        });
        for (int i = 0; i < dateList.size(); i++) {
            int orderTotal = 0;
            BigDecimal orderTotalPrice = BigDecimal.ZERO;
            for (OrderDetailDto order : orderList) {
                if (order.getCreateTime().equals(dateList.get(i))) {
                    orderTotal++;
                    orderTotalPrice = orderTotalPrice.add(new BigDecimal(order.getOrderPrice()));
                }
            }
            orderTotalList.set(i, String.valueOf(orderTotal));
            orderTotalPriceList.set(i, orderTotalPrice.toString());
        }

        trend.setDate(dateList);
        trend.setOrderTotal(orderTotalList);
        trend.setOrderTotalPrice(orderTotalPriceList);
        return trend;
    }

    @Override
    public Map<String, String> queryPending() {
        // 1.准备Request
        SearchRequest request = new SearchRequest("yuanchu_order");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("orderStatus", 10));
        searchSourceBuilder.query(boolQueryBuilder).size(1000);
        // 2.准备DSL
        request.source(searchSourceBuilder);
        // 3.发送请求
        SearchResponse response = null;
        try {
            response = client.search(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException("查询es数据异常");
        }
        // 4.解析响应
        List<OrderDetailDto> orderList = handleResponse(response, OrderDetailDto.class);
        // 获取订单等待发货数量
        long pendingOrder = orderList.stream().filter(order -> order.getOrderStatus() != 20)
                .filter(order -> order.getPayStatus() == 20)
                .filter(order -> order.getDeliveryStatus() == 10).count();
        // 待付款订单(笔)
        long disPayOrders = orderList.stream().filter(order -> order.getOrderStatus() == 10)
                .filter(order -> order.getPayStatus() == 10).count();
        // 售后单(笔)
        long orderRefundTotal = queryIndexDocCount("yuanchu_order_refund");
        Map<String, String> map = new HashMap<>();
        map.put("deliverOrderTotal", String.valueOf(pendingOrder));
        map.put("refundTotal", String.valueOf(orderRefundTotal));
        map.put("paidOrderTotal", String.valueOf(disPayOrders));
        return map;
    }

    @Override
    public Map<String, String> queryConsumption() {
        // 1.准备Request
        SearchRequest request = new SearchRequest("yuanchu_order");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("payStatus", 20));
        boolQueryBuilder.mustNot(QueryBuilders.termQuery("orderStatus", 20));
        searchSourceBuilder.query(boolQueryBuilder).size(1000);
        // 2.准备DSL
        request.source(searchSourceBuilder);
        // 3.发送请求
        SearchResponse response = null;
        try {
            response = client.search(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException("查询es数据异常");
        }
        List<OrderDetailDto> orderList = handleResponse(response, OrderDetailDto.class);
        // 支付订单数
        long payOrders = response.getHits().getTotalHits().value;
        // 付款用户量
        List<Integer> payUserIds = orderList.stream().map(YoshopOrderEntity::getUserId).distinct().collect(Collectors.toList());
        Map<String, String> map = new HashMap<>();
        map.put("consumeUserTotal", String.valueOf(payUserIds.size()));
        map.put("orderTotal", String.valueOf(payOrders));
        return map;
    }

    @Override
    public Map<String, Object> queryOverview() {
        // 获取当天的订单量
        // 获取当前日期
        LocalDate today = LocalDate.now();
        // 当天开始时间（0点0分0秒）
        LocalDateTime startOfDay = today.atStartOfDay();
        long startTimestampInSeconds = startOfDay.toEpochSecond(ZoneOffset.UTC);
        // 当天结束时间（23点59分59秒）
        LocalDateTime endOfDay = today.atTime(23, 59, 59);
        long endTimestampInSeconds = endOfDay.toEpochSecond(ZoneOffset.UTC);

        SearchRequest searchRequest = new SearchRequest("yuanchu_order");
        searchRequest.source().query(QueryBuilders.rangeQuery("createTime")
                .gte(startTimestampInSeconds).lte(endTimestampInSeconds));
        searchRequest.source().size(1000);
        SearchResponse response = null;
        try {
            response = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException("查询es数据异常");
        }
        List<OrderDetailDto> orderList = handleResponse(response, OrderDetailDto.class);
        // 获取当天的订单量
        long orderTotal = orderList.stream().filter(order -> order.getPayStatus() == 20).count();
        // 获取当天的销售额
        BigDecimal priceToday = orderList.stream().filter(order -> order.getPayStatus() == 20)
                .map(order -> new BigDecimal(order.getPayPrice()))
                .reduce(BigDecimal.ZERO, BigDecimal::add)
                .setScale(2, RoundingMode.HALF_UP);
        // 付款会员数
        // 今日付款会员数
        long payUsersToday = orderList.stream().filter(order -> order.getPayStatus() == 20)
                .filter(order -> order.getUser().getGradeId() != 0)
                .map(YoshopOrderEntity::getUserId)
                .distinct().count();
        Map<String, Object> map = new HashMap<>();
        HashMap<String, String> hashMap1 = new HashMap<>();
        hashMap1.put("tday", String.valueOf(orderTotal));
        HashMap<String, String> hashMap2 = new HashMap<>();
        hashMap2.put("tday", String.valueOf(priceToday));
        HashMap<String, String> hashMap3 = new HashMap<>();
        hashMap3.put("tday", String.valueOf(payUsersToday));
        map.put("orderTotal", hashMap1);
        map.put("orderTotalPrice", hashMap2);
        map.put("consumeUserTotal", hashMap3);
        return map;
    }

    @Override
    public List<OrderDetailDto> queryOrderSalesByMonth() {
        // 获取本月的订单量
        // 计算当前月份的第一天和最后一天
        LocalDate firstDayOfMonth = LocalDate.now().withDayOfMonth(1);
        LocalDate lastDayOfMonth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
        // 转换为当前月份的Unix时间戳（精确到秒）
        long startTimestamp = firstDayOfMonth.atStartOfDay(ZoneOffset.UTC).toEpochSecond();
        long endTimestamp = lastDayOfMonth.atTime(23, 59, 59).atZone(ZoneOffset.UTC).toEpochSecond();

        SearchRequest searchRequest = new SearchRequest("yuanchu_order");
        searchRequest.source().query(QueryBuilders.rangeQuery("createTime")
                .gte(startTimestamp).lte(endTimestamp));
        searchRequest.source().size(1000);
        SearchResponse response = null;
        try {
            response = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException("查询es数据异常");
        }
        List<OrderDetailDto> orderList = handleResponse(response, OrderDetailDto.class);
        return orderList;
    }


    @Override
    public List<Map<String, Object>> queryOrderSales() {
        SearchRequest searchRequest = new SearchRequest("yuanchu_order");

        // 设置查询条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.mustNot(QueryBuilders.termQuery("orderStatus", 20));
        searchSourceBuilder.query(boolQueryBuilder);
        // searchSourceBuilder.query(QueryBuilders.matchQuery("payStatus", "20"));

        // 添加聚合
        searchSourceBuilder.aggregation(
                AggregationBuilders
                        .terms("agggoods")
                        .field("goods.goodsId")
                        .size(5)
                        .order(BucketOrder.aggregation("total_pay_price_stats.sum", false))
                        .subAggregation(
                                AggregationBuilders.stats("total_pay_price_stats").field("goods.totalPayPrice")
                        )
                        .subAggregation(
                                AggregationBuilders.stats("total_sales").field("goods.totalNum")
                        )
        );

        searchRequest.source(searchSourceBuilder);

        SearchResponse searchResponse = null;
        try {
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new YuanChuException("查询es数据异常");
        }
        DecimalFormat df = new DecimalFormat("#.##");
        List<Map<String, Object>> list = new ArrayList<>();
        Aggregations aggregations = searchResponse.getAggregations();
        Terms agggoods = aggregations.get("agggoods");
        for (Terms.Bucket bucket : agggoods.getBuckets()) {
            String goodsId = bucket.getKeyAsString();
            ParsedStats totalPayPriceStats = bucket.getAggregations().get("total_pay_price_stats");
            double sum = totalPayPriceStats.getSum();

            // 获取销售数量
            ParsedStats totalSalesStats = bucket.getAggregations().get("total_sales");
            long totalSales = Math.round(totalSalesStats.getSum());
            // 获取聚合结果中的goodsName
            String goodsName = feignGoodsClient.queryGoodsName(Integer.valueOf(goodsId));

            // 将sum和totalSales保留两位小数
            double formattedSum = Double.parseDouble(df.format(sum));
            Map<String, Object> map = new HashMap<>();
            map.put("goods_id", goodsId);
            map.put("goods_name", goodsName); // 添加goodsName到Map中
            map.put("total_pay_price_sum", formattedSum);
            map.put("total_sales", totalSales);
            list.add(map);

            log.info("Goods ID: " + goodsId + ", Goods Name: " + goodsName + ", Total Pay Price Sum: " + formattedSum + ", Total Sales: " + totalSales);
        }
        return list;
    }

    @Override
    public List<OrderDetailDto> queryOrderSalesAll() {
        return null;
    }

    @Override
    public Map<String, String> queryPayOrderCount() {
        // 查询支付订单数量
        SearchRequest searchRequest = new SearchRequest("yuanchu_order");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.mustNot(QueryBuilders.termQuery("orderStatus", 20));
        boolQueryBuilder.must(QueryBuilders.termQuery("payStatus", 20));
        searchSourceBuilder.query(boolQueryBuilder).size(10000);
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = null;
        try {
            response = client.search(searchRequest, RequestOptions.DEFAULT);
        }
        catch (IOException e) {
            throw new YuanChuException("查询es数据异常");
        }
        // 4.1. 获取总条数
        SearchHits searchHits = response.getHits();
        long value = searchHits.getTotalHits().value;
        List<OrderDetailDto> orderList = handleResponse(response, OrderDetailDto.class);
        double orderPrice =  orderList.stream()
                .mapToDouble(order -> Double.parseDouble(order.getPayPrice())) // 映射为Double Stream
                .sum(); // 计算所有订单消费金额的总和
        DecimalFormat df = new DecimalFormat("#.##");
        String orderTotalPrice = df.format(orderPrice);
        // 统计消费用户数量
        long userCount = orderList.stream()
                .mapToInt(OrderDetailDto::getUserId)
                .distinct()
                .count();
        Map<String, String> map = new HashMap<>();
        map.put("pay_order_count", String.valueOf(value));
        map.put("order_total_price", String.valueOf(orderTotalPrice));
        map.put("user_count", String.valueOf(userCount));
        return map;
    }


    private long queryIndexDocCount(String index) {
        // 1.准备Request
        SearchRequest request = new SearchRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("status", 0));
        searchSourceBuilder.query(boolQueryBuilder);
        // 2.准备DSL
        request.source(searchSourceBuilder);
        // 3.发送请求
        SearchResponse response = null;
        try {
            response = client.search(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException("查询es数据异常");
        }
        // 4.解析响应
        // 4. 解析响应
        SearchHits searchHits = response.getHits();
        // 4.1. 获取总条数
        return searchHits.getTotalHits().value;
    }

    private List<YoshopOrderRefundEntity> queryOrderRefunds(Integer userId) {
        // 1.准备Request
        SearchRequest request = new SearchRequest("yuanchu_order_refund");
        // 2.准备DSL
        // 2.1.准备BooleanQuery
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 2.2.添加term
        boolQuery.must(QueryBuilders.termQuery("userId", userId));
        request.source().query(boolQuery);
        request.source().size(1000);
        // 3.发送请求
        SearchResponse response = null;
        try {
            response = client.search(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException("查询es数据异常");
        }
        // 4.解析响应
        return handleResponse(response, YoshopOrderRefundEntity.class);
    }


    private <R> List<R> handleResponse(SearchResponse response, Class<R> type) {
        // 4. 解析响应
        SearchHits searchHits = response.getHits();
        // 4.1. 获取总条数
        long total = searchHits.getTotalHits().value;
        // 4.2. 文档数组
        SearchHit[] hits = searchHits.getHits();
        List<R> resultList = new ArrayList<>();
        // 4.3. 遍历
        for (SearchHit hit : hits) {
            // 获取文档 source
            String json = hit.getSourceAsString();
            // 反序列化
            R object = JSON.parseObject(json, type);
            resultList.add(object);
        }
        return resultList;
    }

    public static long convertStringToSeconds(String dateString) {
        if (StringUtils.isEmpty(dateString)) {
            return 0;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

        try {
            Date date = dateFormat.parse(dateString);
            return date.getTime() / 1000;
        } catch (Exception e) {
            // System.out.println("日期格式不正确：" + e.getMessage());
            return 0; // 返回0表示转换失败
        }
    }


}
// public List<Map<String, Object>> queryOrderSales() {
//     SearchRequest searchRequest = new SearchRequest("yuanchu_order");
//
//     SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder()
//             .query(QueryBuilders.matchQuery("payStatus", "20"))
//             .size(0); // 不需要返回实际的搜索结果，因为我们只关心聚合结果
//
//     // 定义嵌套聚合
//     // 1. 先按商品ID聚合
//     TermsAggregationBuilder goodsAggregation = AggregationBuilders.terms("agggoods")
//             .field("goods.goodsId")
//             .size(5)
//             .order(BucketOrder.aggregation("sales_stats.sum", false));
//
//     // 2. 对每个商品ID计算销售数量和总销售额
//     AggregationBuilder salesStatsAggregation = AggregationBuilders.stats("sales_stats")
//             .field("goods.totalPayPrice");
//
//     // 3. 使用top_hits获取每个商品ID对应的goodsName
//     TopHitsAggregationBuilder topHitsAgg = AggregationBuilders.topHits("top_docs")
//             .size(1) // 只取每个桶下的一条记录
//             .fetchSource(new String[]{"goods.goodsName"}, null); // 投影需要的字段
//
//     // 将子聚合添加到商品ID聚合中
//     goodsAggregation.subAggregation(salesStatsAggregation).subAggregation(topHitsAgg);
//
//     searchSourceBuilder.aggregation(goodsAggregation);
//     searchRequest.source(searchSourceBuilder);
//     // 发送请求
//     SearchResponse searchResponse = null;
//     try {
//         searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
//     } catch (IOException e) {
//         throw new YuanChuException("查询es数据异常");
//     }
//     DecimalFormat df = new DecimalFormat("#.##");
//     List<Map<String, Object>> list = new ArrayList<>();
//     Aggregations aggregations = searchResponse.getAggregations();
//     Terms agggoods = aggregations.get("agggoods");
//
//     // 解析聚合结果
//     // 解析聚合结果
//     for (Terms.Bucket bucket : agggoods.getBuckets()) {
//         String goodsId = bucket.getKeyAsString();
//         ParsedStats salesStats = bucket.getAggregations().get("sales_stats");
//         double sum = salesStats.getSum();
//         double totalSales = salesStats.getCount(); // 假设count代表销售数量
//
//         // 获取top_hits子聚合结果
//         ParsedTopHits topHits = bucket.getAggregations().get("top_docs");
//         SearchHit[] hits = topHits.getHits().getHits();
//         String goodsName = ""; // 初始化goodsName为空字符串
//
//         // 遍历hits[0]._source.goods列表，找到与goodsId匹配的商品名
//         for (Map<String, Object> goodsItem : (List<Map<String, Object>>) hits[0].getSourceAsMap().get("goods")) {
//             if (goodsItem.containsKey("goodsId") && goodsItem.get("goodsId").equals(goodsId)) {
//                 goodsName = (String) goodsItem.get("goodsName");
//                 break; // 找到匹配的商品名后退出循环
//             }
//         }
//
//         // 如果goodsName仍然为空，说明没有找到与goodsId匹配的商品名
//         if (goodsName.isEmpty()) {
//             log.error("Missing goodsName for goodsId: {}", goodsId);
//         } else {
//             double formattedSum = Double.parseDouble(df.format(sum));
//             Map<String, Object> map = new HashMap<>();
//             map.put("goods_id", goodsId);
//             map.put("goods_name", goodsName);
//             map.put("total_sales", totalSales);
//             map.put("total_pay_price_sum", formattedSum);
//             list.add(map);
//
//             log.info("Goods ID: {}, Goods Name: {}, Total Sales: {}, Total Pay Price Sum: {}", goodsId, goodsName, totalSales, formattedSum);
//         }
//     }
//
//     return list;
// }